﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


using System.IO;



namespace HA.ModFlow.Domain.DomainLayer
{
   public static  class ModflowBinaryFileReader
    {


        /// <summary>
        /// 读整个文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
       public static List<BinaryFileData> ReadModflowBinaryFile(string fileName)
       {
           FileStream fs = new FileStream(fileName, FileMode.Open);

           BinaryReader reader = new BinaryReader(fs);

           List<BinaryFileData> result = new List<BinaryFileData>();

           try
           {
               //while (reader.PeekChar() != -1)
               while(reader.BaseStream.Position<reader.BaseStream.Length)
               {
                   BinaryFileData mfBinaryObj = new BinaryFileData();

                   mfBinaryObj.KSTP = reader.ReadInt32();//时间步长
                   mfBinaryObj.KPER = reader.ReadInt32();  // // 应力期
                   mfBinaryObj.CurrentEllapseTime = reader.ReadSingle();//当前应力期逝去时间
                   mfBinaryObj.TotalEllapseTime = reader.ReadSingle();//总的应力期逝去时间
                   mfBinaryObj.TEXT = reader.ReadChars(16);  // 'Text
                   mfBinaryObj.NCOL = reader.ReadInt32();  // '列
                   mfBinaryObj.NROW = reader.ReadInt32();  // '行          
                   mfBinaryObj.ILAY = reader.ReadInt32();  //'层


                   bool isExist = false;
                   BinaryFileData existData = null;

                   foreach (BinaryFileData data in result)
                   {
                       if (data.TotalEllapseTime == mfBinaryObj.TotalEllapseTime )
                       {
                           isExist = true;
                           existData = data;
                           break;
                       }
                   }

                   if (isExist == true)
                   {
                       double[, ,] values = existData.values.Clone() as double[, ,];

                       existData.values = new double[mfBinaryObj.NROW, mfBinaryObj.NCOL, mfBinaryObj.ILAY];

                       for (int layer = 0; layer < existData.ILAY; layer++)
                       {
                           for (int row = 0; row < mfBinaryObj.NROW; row++)
                           {
                               for (int col = 0; col < mfBinaryObj.NCOL; col++)
                               {
                                   existData.values[row, col, layer] = values[row, col, layer];
                               }
                           }
                       }

                       existData.ILAY = mfBinaryObj.ILAY;

                       for (int layer = existData.ILAY - 1; layer < existData.ILAY; layer++)
                       {
                           for (int row = 0; row < mfBinaryObj.NROW; row++)
                           {
                               for (int col = 0; col < mfBinaryObj.NCOL; col++)
                               {
                                   existData.values[row, col, layer] = reader.ReadSingle();
                               }
                           }
                       }
                   }
                   else
                   {
                       mfBinaryObj.values = new double[mfBinaryObj.NROW, mfBinaryObj.NCOL, mfBinaryObj.ILAY];

                       for (int layer = 0; layer < 1; layer++)
                       {
                           for (int row = 0; row < mfBinaryObj.NROW; row++)
                           {
                               for (int col = 0; col < mfBinaryObj.NCOL; col++)
                               {
                                   mfBinaryObj.values[row, col, layer] = reader.ReadSingle();
                               }
                           }
                       }
                       result.Add(mfBinaryObj);
                   }
               }

               fs.Close();
               fs.Dispose();
               reader.Close();
               reader.Dispose();

               return result;

           }
           catch 
           {
               fs.Close();
               fs.Dispose();
               reader.Close();
               reader.Dispose();

               return null;
           }


       
       }





       /// <summary>
       /// 返回这个文件共有多少段，引用传递值存单个段落有多少字节
       /// </summary>
       /// <param name="fileName"></param>
       /// <param name="partLength">存储单段字节数</param>
       /// <returns></returns>
       public static int GetBinaryFilePartLength(string fileName, ref long partLength) 
       {
           FileStream fs = new FileStream(fileName, FileMode.Open);

           BinaryReader reader = new BinaryReader(fs);

           long length = reader.BaseStream.Length;

           if (length == 0)
           {
               fs.Close();
               reader.Close();
               return 0;
           }

           long singleLength = 0;

           try
           {
               //if (reader.PeekChar() != -1)
                   if(reader.BaseStream.Position<reader.BaseStream.Length)
               {
                   BinaryFileData mfBinaryObj = new BinaryFileData();

                   //reader.BaseStream.Position = 0;


                   mfBinaryObj.KSTP = reader.ReadInt32();//时间步长
                   singleLength += 4;
                   mfBinaryObj.KPER = reader.ReadInt32();  // // 应力期
                   singleLength += 4;
                   mfBinaryObj.CurrentEllapseTime = reader.ReadSingle();//当前应力期逝去时间
                   singleLength += 4;
                   mfBinaryObj.TotalEllapseTime = reader.ReadSingle();//总的应力期逝去时间
                   singleLength += 4;
                   mfBinaryObj.TEXT = reader.ReadChars(16);  // 'Text
                   singleLength += 16;
                   mfBinaryObj.NCOL = reader.ReadInt32();  // '列
                   singleLength += 4;
                   mfBinaryObj.NROW = reader.ReadInt32();  // '行       
                   singleLength += 4;
                   mfBinaryObj.ILAY = reader.ReadInt32();  //'层
                   singleLength += 4;




                   mfBinaryObj.values = new double[mfBinaryObj.NROW, mfBinaryObj.NCOL, mfBinaryObj.ILAY];

                   for (int layer = 0; layer < mfBinaryObj.ILAY; layer++)
                   {
                       for (int row = 0; row < mfBinaryObj.NROW; row++)
                       {
                           for (int col = 0; col < mfBinaryObj.NCOL; col++)
                           {
                               mfBinaryObj.values[row, col, layer] = reader.ReadSingle();
                               singleLength += 4;
                           }
                       }
                   }


               }

               fs.Close();
               fs.Dispose();
               reader.Close();
               reader.Dispose();

               partLength = singleLength;

               int num;
               if (singleLength == 0)
               {
                   num = 0;
               }
               else
               {
                   long n = length / singleLength;
                   num = Convert.ToInt32(n);
               }

               return num;

           }
           catch 
           {
               fs.Close();
               fs.Dispose();
               reader.Close();
               reader.Dispose();

               return 0;
           }
       
       
       }




        /// <summary>
        /// 读取任意index段的内容。
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="index">要读哪一段的</param>
        /// <param name="partLength">单段有多少字节</param>
        /// <returns></returns>
       public static BinaryFileData ReadPartBinaryFile(string fileName, int index, long partLength)
       {


           FileStream fs = new FileStream(fileName, FileMode.Open);

           BinaryReader reader = new BinaryReader(fs);

           reader.BaseStream.Position = partLength;

           BinaryFileData mfBinaryObj = new BinaryFileData();

           try
           {

               //if (reader.PeekChar() != -1)
               if (reader.BaseStream.Position < reader.BaseStream.Length)
               {
                   //reader.BaseStream.Position = 0;


                   mfBinaryObj.KSTP = reader.ReadInt32();//时间步长
                   mfBinaryObj.KPER = reader.ReadInt32();  // // 应力期
                   mfBinaryObj.CurrentEllapseTime = reader.ReadSingle();//当前应力期逝去时间
                   mfBinaryObj.TotalEllapseTime = reader.ReadSingle();//总的应力期逝去时间
                   mfBinaryObj.TEXT = reader.ReadChars(16);  // 'Text
                   mfBinaryObj.NCOL = reader.ReadInt32();  // '列
                   mfBinaryObj.NROW = reader.ReadInt32();  // '行          
                   mfBinaryObj.ILAY = reader.ReadInt32();  //'层



                   mfBinaryObj.values = new double [ mfBinaryObj.NROW, mfBinaryObj.NCOL,mfBinaryObj.ILAY];

                   for (int layer = 0; layer < mfBinaryObj.ILAY; layer++)
                   {
                       for (int row = 0; row < mfBinaryObj.NROW; row++)
                       {
                           for (int col = 0; col < mfBinaryObj.NCOL; col++)
                           {
                               mfBinaryObj.values[row,col,layer] = reader.ReadSingle();
                           }
                       }
                   }

                   fs.Close();
                   fs.Dispose();
                   reader.Close();
                   reader.Dispose();

                   return mfBinaryObj;

               }

               fs.Close();
               fs.Dispose();
               reader.Close();
               reader.Dispose();

               return null;



           }
           catch 
           {
               fs.Close();
               fs.Dispose();
               reader.Close();
               reader.Dispose();

               return null;
           }
            
       
       
       }



    }


   public class BinaryFileData
   {

       public int KSTP;  //时间不长
       public int KPER;  // // '应力期
       public double    CurrentEllapseTime;//当前应力期逝去时间
       public double   TotalEllapseTime;//总的逝去时间
       public char[] TEXT;  // 'concentration
       public int NCOL;  // '列
       public int NROW;  // '行          
       public int ILAY;  //'层

       public double   [, ,] values; //浓度值  存放顺序为  Row，Col，Layer



      

   }


}
